// VMR9Graph.h: interface for the CVMR9Graph class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_EVRGRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_)
#define AFX_EVRGRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <dshow.h>
#include <D3d9.h>
#include <Vmr9.h>
#include <d3dx9tex.h>
#include <uuids.h>
#include <evr.h>

#pragma comment( lib, "strmiids.lib" )
#pragma comment( lib, "Quartz.lib" )
#pragma comment( lib, "D3D9.lib" )
#pragma comment( lib, "d3dx9.lib" )

#define WM_MEDIA_NOTIFY		(WM_APP + 1)

#define DEF_ADD_COL_CONTROL

//#define DEF_VMR9

class CEVRGraph  
{
	// Constructor / destructor
public:
	CEVRGraph();
	CEVRGraph(HWND MediaWindow, int NumberOfStream = 4);
	virtual ~CEVRGraph();

	void	InitCOM();	//COM Initialization

	typedef enum { 
		ENUM_VCONT_BR = ProcAmpControl9_Brightness , 
		ENUM_VCONT_CONT = ProcAmpControl9_Contrast , 
		ENUM_VCONT_HUE = ProcAmpControl9_Hue, 
		ENUM_VCONT_SAT = ProcAmpControl9_Saturation  
	} VIDEO_CONT;

	// Methods
public:
	// Graph configuration
	void SetNumberOfLayer(int nNumberOfLayer);
	BOOL SetMediaWindow(HWND MediaWindow);
	BOOL SetMediaFile(HWND MediaWindow, LPCTSTR pszFileName, BOOL bLetteBox = TRUE, int nLayer = 0);
	BOOL PreserveAspectRatio(BOOL bPreserve = TRUE);
	IBaseFilter* AddFilter(LPCWSTR pszName, const GUID& clsid);

	// Graph control
	int GetState();
	BOOL IsRunning();
	BOOL PlayGraph();
	BOOL StopGraph();
	BOOL PauseGraph();

	IMediaControl* GetPtrMediaControl();
	IMediaSeeking* GetPtrMediaSeeking();
	IBasicAudio* GetPtrBasicAudio();
	IMediaEventEx* GetPtrMediaEventEx();

	// Layer control
	BOOL GetVideoRect(LPRECT pRect);
	int GetAlphaLayer(int nLayer);
	BOOL SetAlphaLayer(int nLayer, int nAlpha);
	DWORD GetLayerZOrder(int nLayer);
	BOOL SetLayerZOrder(int nLayer, DWORD dwZOrder);
	BOOL SetLayerRect(int nLayer, RECT layerRect);

	//Video control
	float GetBrightness();
	BOOL SetBrightness(float percent);

#ifdef DEF_ADD_COL_CONTROL
	float GetVideoColControl(int nIndexVMRAmpFlag);
	BOOL SetVideoColControl(int nIndexVMRAmpFlag, float percent);
#endif

	long GetPlayDuration();
	long GetPlayPos();
	BOOL SetPlayPos(long msec);
	BOOL GetNativeVideoSize(LONG* pWidth, LONG* pHeight, LONG* pARWidth, LONG* pARHeight);
	int	 GetFps();

	// Bitmap control
	//BOOL SetBitmap(LPCTSTR pszBitmapFileName, int nAlpha, COLORREF cTransColor, RECT bitmapRect);
	//BOOL SetBitmapParams(int nAlpha, COLORREF cTransColor, RECT bitmapRect);
	BOOL CaptureImage(LPCTSTR szFile);

	// Reflected from window
	BOOL Repaint();
	BOOL Resize();

	// helper
	LPCTSTR GetLastError();

	//
	HRESULT WaitForState(OAFilterState fsReq);

protected:
	// INIT helper methods
	void InitDefaultValues();
	void ReleaseAllInterfaces();

	// GRAPH methods
	BOOL BuildFilterGraphVMR(LPCWSTR pszFileName, int nLayer = 0);
	BOOL BuildVMR();
	BOOL BuildSoundRenderer();
	BOOL RenderGraph();
	BOOL BuildFilterGraphClassic(LPCWSTR pszFileName);

	// DIRECT3D methods
	//BOOL BuildDirect3d();
	//void ReleaseDirect3d();
	//BOOL GetBitmapSize(LPCTSTR pszBitmapFileName,long& lHeight, long& lWidth);

	// LAYER helper methods
	BOOL IsValidLayer(int nLayer);
	VMR9NormalizedRect NormalizeRect9(LPRECT pRect);
	NORMALIZEDRECT NormalizeRect(LPRECT pRect);

	// DSOW helper methods
	HRESULT AddToRot(IUnknown *pUnkGraph);
	void RemoveFromRot();
	IPin* GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir);
	void ReportError(LPCTSTR pszError, HRESULT hrCode);
	HRESULT GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext);
	BOOL RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilter);
	HRESULT AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID& clsid, IBaseFilter **ppF);

	//Audio control
	long GetVolume();
	BOOL SetVolume(long volume);

protected:
	int							m_Mode;	//0: EVR, 1: classical
	DWORD						m_dwRotId;
	TCHAR						m_pszErrorDescription[1024+MAX_ERROR_TEXT_LEN];
	int							m_nNumberOfStream;
	// MEDIA WINDOW
	HWND						m_hMediaWindow;
	// SRC interfaces array
	IBaseFilter*				m_srcFilterArray[10];
	// SOUND interfaces
	IBaseFilter*				m_pDirectSoundFilter;
	// GRAPH interfaces
	IUnknown*					m_pGraphUnknown;
	IGraphBuilder*				m_pGraphBuilder;
	IFilterGraph2*				m_pFilterGraph2;
	IMediaControl*				m_pMediaControl;
	IMediaEventEx*				m_pMediaEventEx;
	
#ifdef DEF_VMR9
	IBaseFilter*				m_pVMRBaseFilter;	// VMR
#endif
	IBaseFilter*				m_pEVRBaseFilter;	// EVR

	// EVR interfaces
	IEVRFilterConfig*			m_pEVRFilterConfig; 
#ifdef DEF_VMR9
	IVMRFilterConfig9*			m_pVMRFilterConfig9;
#endif
	IVMRMixerBitmap9*			m_pVMRMixerBitmap9;
	IVMRMixerControl9*			m_pVMRMixerControl9;
	IVMRMonitorConfig9*			m_pVMRMonitorConfig9;
	IVMRWindowlessControl9*		m_pVMRWindowlessControl9;

	// classical interfaces
	IVideoWindow*				m_pVideoWindow;
	IBasicVideo*				m_pBasicVideo;
	IBasicAudio*				m_pBasicAudio;

	// DIRECT3D interfaces
	//IDirect3D9*				m_pD3DDirect3d;
	//IDirect3DDevice9*			m_pD3DDevice;
	//IDirect3DSurface9*		m_pD3DSurface;

	// Attributes
protected:
	BOOL						m_bMirrored;
	BOOL						m_bFlipped;
	BOOL						m_bFullScrn;
	WCHAR						m_szMediaFile[256];
public:
	void						OnMediaNotify();
	BOOL						GetMirrored();
	void						SetMirrored(BOOL b);
	BOOL						GetFlipped();
	void						SetFlipped(BOOL b);
	BOOL						IsFullScreen();
	void						SetFullScreen(BOOL bSet);
	void						Rotate180();
	void						SetAudioVolume(int volume);
	int							GetAudioVolume();
	BOOL						GetVideoSize(LONG* pWidth, LONG* pHeight);
	void						SetSpeed(double speed);
	double						GetSpeed();

};

#endif // !defined(AFX_EVRGRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_)
